//gcc -o hello hello.c -lX11 -lGL -lGLU

// includes  do C 
#include<stdio.h>
#include<stdlib.h>
// includes  da API do X11
#include<X11/X.h>
#include<X11/Xlib.h>

// includes  do Opengl 
#include<GL/gl.h>
#include<GL/glx.h>
#include<GL/glu.h>


//variaveis do opengl e do x11

Display                 *dpy;	
Window                  root;
GLint                   att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
XVisualInfo             *vi;
Colormap                cmap;
XSetWindowAttributes    swa;
Window                  win;
GLXContext              glc;
XWindowAttributes       gwa;
XEvent                  xev;

void DrawAQuad() {
 glClearColor(1.0, 1.0, 1.0, 1.0); // especifica os valores de limpeza do buffer de cores 
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // limpa o buffer usando o valor determinado em glClearColor

 glMatrixMode(GL_PROJECTION);  // especifica a matriz utilizada 
 glLoadIdentity(); // transforma a matriz ativa na identidade 
 glOrtho(-1., 1., -1., 1., 1., 20.); // constroi a projecao ortogonal 

 glMatrixMode(GL_MODELVIEW);// especifica a matriz utilizada 
 glLoadIdentity(); // transforma a matriz ativa na identidade 
 gluLookAt(0., 0., 10., 0., 0., 0., 0., 1., 0.); // define a posicao do observador da imagem 

 glBegin(GL_QUADS); // Delimita os vertices do objeto no comentario 
  glColor3f(1., 0., 0.); glVertex3f(-.75, -.75, 0.); // posicao do vertice do quadrado colorido 
  glColor3f(0., 1., 0.); glVertex3f( .75, -.75, 0.);
  glColor3f(0., 0., 1.); glVertex3f( .75,  .75, 0.);
  glColor3f(1., 1., 0.); glVertex3f(-.75,  .75, 0.);
 glEnd(); } 
 
int main(int argc, char *argv[]) {

 dpy = XOpenDisplay(NULL); // abrindo o display para visualizacao 
 
 if(dpy == NULL) {
 	printf("\n\t Impossivel conectar ao display \n\n");
        exit(0); }
        
 root = DefaultRootWindow(dpy);

 vi = glXChooseVisual(dpy, 0, att);  // rernando o display determinado em dpy 

 if(vi == NULL) {
	printf("\n\tno appropriate visual found\n\n");
        exit(0); } 
 else {
	printf("\n\tvisual %p selected\n", (void *)vi->visualid); }/* %p creates hexadecimal output like in glxinfo */


 cmap = XCreateColormap(dpy, root, vi->visual, AllocNone);// determina um mapa de cores 

 swa.colormap = cmap; // determina um mapa de cores 
 swa.event_mask = ExposureMask | KeyPressMask;   // manipula os evetos exposicao e tecla pressionada da janela 
 
 win = XCreateWindow(dpy, root, 0, 0, 600, 600, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa); // cria a janela 

 XMapWindow(dpy, win); // mapeia a janela 
 XStoreName(dpy, win, "Primeiro Programa"); // nome da janela 
 
 glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); // cria o contexto opengl na janela 
 glXMakeCurrent(dpy, win, glc); // faz a janela ser a janela manipulada atualmente 
 
 glEnable(GL_DEPTH_TEST);  // habilita o controle de profundidade ao desenhar 
 
 while(1) { // tratamento dos eventos 
 	XNextEvent(dpy, &xev);
        
        if(xev.type == Expose) { // ao expor a janela 
        	XGetWindowAttributes(dpy, win, &gwa);
                glViewport(0, 0, gwa.width, gwa.height);
        	DrawAQuad();  //  desenha a janela 
                glXSwapBuffers(dpy, win); }s
                
	else if(xev.type == KeyPress) { // se alguma tecla eh pressionada termina o programa 
        	glXMakeCurrent(dpy, None, NULL);
 		glXDestroyContext(dpy, glc);
 		XDestroyWindow(dpy, win);
 		XCloseDisplay(dpy);
 		exit(0); }
	} /* this closes while(1) { */
} /* this is the } which closes int main(int argc, char *argv[]) { */